//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension AmplifyUIBuilder {
    // MARK: Enums

    public enum FixedPosition: String, CustomStringConvertible, Codable, _SotoSendable {
        case first
        public var description: String { return self.rawValue }
    }

    public enum FormActionType: String, CustomStringConvertible, Codable, _SotoSendable {
        case create
        case update
        public var description: String { return self.rawValue }
    }

    public enum FormButtonsPosition: String, CustomStringConvertible, Codable, _SotoSendable {
        case bottom
        case top
        case topAndBottom = "top_and_bottom"
        public var description: String { return self.rawValue }
    }

    public enum FormDataSourceType: String, CustomStringConvertible, Codable, _SotoSendable {
        /// Will use passed in hooks to use when creating a form from scratch
        case custom = "Custom"
        /// Will use a provided Amplify DataStore enabled API
        case dataStore = "DataStore"
        public var description: String { return self.rawValue }
    }

    public enum SortDirection: String, CustomStringConvertible, Codable, _SotoSendable {
        case asc = "ASC"
        case desc = "DESC"
        public var description: String { return self.rawValue }
    }

    public enum TokenProviders: String, CustomStringConvertible, Codable, _SotoSendable {
        /// The figma token provider.
        case figma
        public var description: String { return self.rawValue }
    }

    public enum FieldPosition: AWSEncodableShape & AWSDecodableShape, _SotoSendable {
        /// The field position is below the field specified by the string.
        case below(String)
        /// The field position is fixed and doesn't change in relation to other fields.
        case fixed(FixedPosition)
        /// The field position is to the right of the field specified by the string.
        case rightOf(String)

        public init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            guard container.allKeys.count == 1, let key = container.allKeys.first else {
                let context = DecodingError.Context(
                    codingPath: container.codingPath,
                    debugDescription: "Expected exactly one key, but got \(container.allKeys.count)"
                )
                throw DecodingError.dataCorrupted(context)
            }
            switch key {
            case .below:
                let value = try container.decode(String.self, forKey: .below)
                self = .below(value)
            case .fixed:
                let value = try container.decode(FixedPosition.self, forKey: .fixed)
                self = .fixed(value)
            case .rightOf:
                let value = try container.decode(String.self, forKey: .rightOf)
                self = .rightOf(value)
            }
        }

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .below(let value):
                try container.encode(value, forKey: .below)
            case .fixed(let value):
                try container.encode(value, forKey: .fixed)
            case .rightOf(let value):
                try container.encode(value, forKey: .rightOf)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case below
            case fixed
            case rightOf
        }
    }

    public enum FormStyleConfig: AWSEncodableShape & AWSDecodableShape, _SotoSendable {
        /// A reference to a design token to use to bind the form's style properties to an existing theme.
        case tokenReference(String)
        /// The value of the style setting.
        case value(String)

        public init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            guard container.allKeys.count == 1, let key = container.allKeys.first else {
                let context = DecodingError.Context(
                    codingPath: container.codingPath,
                    debugDescription: "Expected exactly one key, but got \(container.allKeys.count)"
                )
                throw DecodingError.dataCorrupted(context)
            }
            switch key {
            case .tokenReference:
                let value = try container.decode(String.self, forKey: .tokenReference)
                self = .tokenReference(value)
            case .value:
                let value = try container.decode(String.self, forKey: .value)
                self = .value(value)
            }
        }

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .tokenReference(let value):
                try container.encode(value, forKey: .tokenReference)
            case .value(let value):
                try container.encode(value, forKey: .value)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case tokenReference
            case value
        }
    }

    // MARK: Shapes

    public struct ActionParameters: AWSEncodableShape & AWSDecodableShape {
        /// The HTML anchor link to the location to open. Specify this value for a navigation action.
        public let anchor: ComponentProperty?
        /// A dictionary of key-value pairs mapping Amplify Studio properties to fields in a data model. Use when the action performs an operation on an Amplify DataStore model.
        public let fields: [String: ComponentProperty]?
        /// Specifies whether the user should be signed out globally. Specify this value for an auth sign out action.
        public let global: ComponentProperty?
        /// The unique ID of the component that the ActionParameters apply to.
        public let id: ComponentProperty?
        /// The name of the data model. Use when the action performs an operation on an Amplify DataStore model.
        public let model: String?
        /// A key-value pair that specifies the state property name and its initial value.
        public let state: MutationActionSetStateParameter?
        /// The element within the same component to modify when the action occurs.
        public let target: ComponentProperty?
        /// The type of navigation action. Valid values are url and anchor. This value is required for a navigation action.
        public let type: ComponentProperty?
        /// The URL to the location to open. Specify this value for a navigation action.
        public let url: ComponentProperty?

        public init(anchor: ComponentProperty? = nil, fields: [String: ComponentProperty]? = nil, global: ComponentProperty? = nil, id: ComponentProperty? = nil, model: String? = nil, state: MutationActionSetStateParameter? = nil, target: ComponentProperty? = nil, type: ComponentProperty? = nil, url: ComponentProperty? = nil) {
            self.anchor = anchor
            self.fields = fields
            self.global = global
            self.id = id
            self.model = model
            self.state = state
            self.target = target
            self.type = type
            self.url = url
        }

        private enum CodingKeys: String, CodingKey {
            case anchor
            case fields
            case global
            case id
            case model
            case state
            case target
            case type
            case url
        }
    }

    public struct Component: AWSDecodableShape {
        /// The unique ID of the Amplify app associated with the component.
        public let appId: String
        /// The information to connect a component's properties to data at runtime. You can't specify tags as a valid property for bindingProperties.
        public let bindingProperties: [String: ComponentBindingPropertiesValue]
        /// A list of the component's ComponentChild instances.
        public let children: [ComponentChild]?
        /// The data binding configuration for the component's properties. Use this for a collection component. You can't specify tags as a valid property for collectionProperties.
        public let collectionProperties: [String: ComponentDataConfiguration]?
        /// The type of the component. This can be an Amplify custom UI component or another custom component.
        public let componentType: String
        /// The time that the component was created.
        public let createdAt: Date
        /// The name of the backend environment that is a part of the Amplify app.
        public let environmentName: String
        /// Describes the events that can be raised on the component. Use for the workflow feature in Amplify Studio that allows you to bind events and actions to components.
        public let events: [String: ComponentEvent]?
        /// The unique ID of the component.
        public let id: String
        /// The time that the component was modified.
        public let modifiedAt: Date?
        /// The name of the component.
        public let name: String
        /// Describes the component's properties that can be overriden in a customized instance of the component. You can't specify tags as a valid property for overrides.
        public let overrides: [String: [String: String]]
        /// Describes the component's properties. You can't specify tags as a valid property for properties.
        public let properties: [String: ComponentProperty]
        /// The schema version of the component when it was imported.
        public let schemaVersion: String?
        /// The unique ID of the component in its original source system, such as Figma.
        public let sourceId: String?
        /// One or more key-value pairs to use when tagging the component.
        public let tags: [String: String]?
        /// A list of the component's variants. A variant is a unique style configuration of a main component.
        public let variants: [ComponentVariant]

        public init(appId: String, bindingProperties: [String: ComponentBindingPropertiesValue], children: [ComponentChild]? = nil, collectionProperties: [String: ComponentDataConfiguration]? = nil, componentType: String, createdAt: Date, environmentName: String, events: [String: ComponentEvent]? = nil, id: String, modifiedAt: Date? = nil, name: String, overrides: [String: [String: String]], properties: [String: ComponentProperty], schemaVersion: String? = nil, sourceId: String? = nil, tags: [String: String]? = nil, variants: [ComponentVariant]) {
            self.appId = appId
            self.bindingProperties = bindingProperties
            self.children = children
            self.collectionProperties = collectionProperties
            self.componentType = componentType
            self.createdAt = createdAt
            self.environmentName = environmentName
            self.events = events
            self.id = id
            self.modifiedAt = modifiedAt
            self.name = name
            self.overrides = overrides
            self.properties = properties
            self.schemaVersion = schemaVersion
            self.sourceId = sourceId
            self.tags = tags
            self.variants = variants
        }

        private enum CodingKeys: String, CodingKey {
            case appId
            case bindingProperties
            case children
            case collectionProperties
            case componentType
            case createdAt
            case environmentName
            case events
            case id
            case modifiedAt
            case name
            case overrides
            case properties
            case schemaVersion
            case sourceId
            case tags
            case variants
        }
    }

    public struct ComponentBindingPropertiesValue: AWSEncodableShape & AWSDecodableShape {
        /// Describes the properties to customize with data at runtime.
        public let bindingProperties: ComponentBindingPropertiesValueProperties?
        /// The default value of the property.
        public let defaultValue: String?
        /// The property type.
        public let type: String?

        public init(bindingProperties: ComponentBindingPropertiesValueProperties? = nil, defaultValue: String? = nil, type: String? = nil) {
            self.bindingProperties = bindingProperties
            self.defaultValue = defaultValue
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case bindingProperties
            case defaultValue
            case type
        }
    }

    public struct ComponentBindingPropertiesValueProperties: AWSEncodableShape & AWSDecodableShape {
        /// An Amazon S3 bucket.
        public let bucket: String?
        /// The default value to assign to the property.
        public let defaultValue: String?
        /// The field to bind the data to.
        public let field: String?
        /// The storage key for an Amazon S3 bucket.
        public let key: String?
        /// An Amplify DataStore model.
        public let model: String?
        /// A list of predicates for binding a component's properties to data.
        public let predicates: [Predicate]?
        /// The name of a component slot.
        public let slotName: String?
        /// An authenticated user attribute.
        public let userAttribute: String?

        public init(bucket: String? = nil, defaultValue: String? = nil, field: String? = nil, key: String? = nil, model: String? = nil, predicates: [Predicate]? = nil, slotName: String? = nil, userAttribute: String? = nil) {
            self.bucket = bucket
            self.defaultValue = defaultValue
            self.field = field
            self.key = key
            self.model = model
            self.predicates = predicates
            self.slotName = slotName
            self.userAttribute = userAttribute
        }

        private enum CodingKeys: String, CodingKey {
            case bucket
            case defaultValue
            case field
            case key
            case model
            case predicates
            case slotName
            case userAttribute
        }
    }

    public struct ComponentChild: AWSEncodableShape & AWSDecodableShape {
        /// The list of ComponentChild instances for this component.
        public let children: [ComponentChild]?
        /// The type of the child component.
        public let componentType: String
        /// Describes the events that can be raised on the child component. Use for the workflow feature in Amplify Studio that allows you to bind events and actions to components.
        public let events: [String: ComponentEvent]?
        /// The name of the child component.
        public let name: String
        /// Describes the properties of the child component. You can't specify tags as a valid property for properties.
        public let properties: [String: ComponentProperty]
        /// The unique ID of the child component in its original source system, such as Figma.
        public let sourceId: String?

        public init(children: [ComponentChild]? = nil, componentType: String, events: [String: ComponentEvent]? = nil, name: String, properties: [String: ComponentProperty], sourceId: String? = nil) {
            self.children = children
            self.componentType = componentType
            self.events = events
            self.name = name
            self.properties = properties
            self.sourceId = sourceId
        }

        private enum CodingKeys: String, CodingKey {
            case children
            case componentType
            case events
            case name
            case properties
            case sourceId
        }
    }

    public final class ComponentConditionProperty: AWSEncodableShape & AWSDecodableShape {
        /// The value to assign to the property if the condition is not met.
        public let `else`: ComponentProperty?
        /// The name of a field. Specify this when the property is a data model.
        public let field: String?
        /// The value of the property to evaluate.
        public let operand: String?
        /// The type of the property to evaluate.
        public let operandType: String?
        /// The operator to use to perform the evaluation, such as eq to represent equals.
        public let `operator`: String?
        /// The name of the conditional property.
        public let property: String?
        /// The value to assign to the property if the condition is met.
        public let then: ComponentProperty?

        public init(else: ComponentProperty? = nil, field: String? = nil, operand: String? = nil, operandType: String? = nil, operator: String? = nil, property: String? = nil, then: ComponentProperty? = nil) {
            self.`else` = `else`
            self.field = field
            self.operand = operand
            self.operandType = operandType
            self.`operator` = `operator`
            self.property = property
            self.then = then
        }

        private enum CodingKeys: String, CodingKey {
            case `else`
            case field
            case operand
            case operandType
            case `operator`
            case property
            case then
        }
    }

    public struct ComponentDataConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// A list of IDs to use to bind data to a component. Use this property to bind specifically chosen data, rather than data retrieved from a query.
        public let identifiers: [String]?
        /// The name of the data model to use to bind data to a component.
        public let model: String
        /// Represents the conditional logic to use when binding data to a component. Use this property to retrieve only a subset of the data in a collection.
        public let predicate: Predicate?
        /// Describes how to sort the component's properties.
        public let sort: [SortProperty]?

        public init(identifiers: [String]? = nil, model: String, predicate: Predicate? = nil, sort: [SortProperty]? = nil) {
            self.identifiers = identifiers
            self.model = model
            self.predicate = predicate
            self.sort = sort
        }

        private enum CodingKeys: String, CodingKey {
            case identifiers
            case model
            case predicate
            case sort
        }
    }

    public struct ComponentEvent: AWSEncodableShape & AWSDecodableShape {
        /// The action to perform when a specific event is raised.
        public let action: String?
        /// Binds an event to an action on a component. When you specify a bindingEvent, the event is called when the action is performed.
        public let bindingEvent: String?
        /// Describes information about the action.
        public let parameters: ActionParameters?

        public init(action: String? = nil, bindingEvent: String? = nil, parameters: ActionParameters? = nil) {
            self.action = action
            self.bindingEvent = bindingEvent
            self.parameters = parameters
        }

        private enum CodingKeys: String, CodingKey {
            case action
            case bindingEvent
            case parameters
        }
    }

    public final class ComponentProperty: AWSEncodableShape & AWSDecodableShape {
        /// The information to bind the component property to data at runtime.
        public let bindingProperties: ComponentPropertyBindingProperties?
        /// The information to bind the component property to form data.
        public let bindings: [String: FormBindingElement]?
        /// The information to bind the component property to data at runtime. Use this for collection components.
        public let collectionBindingProperties: ComponentPropertyBindingProperties?
        /// The name of the component that is affected by an event.
        public let componentName: String?
        /// A list of component properties to concatenate to create the value to assign to this component property.
        public let concat: [ComponentProperty]?
        /// The conditional expression to use to assign a value to the component property.
        public let condition: ComponentConditionProperty?
        /// Specifies whether the user configured the property in Amplify Studio after importing it.
        public let configured: Bool?
        /// The default value to assign to the component property.
        public let defaultValue: String?
        /// An event that occurs in your app. Use this for workflow data binding.
        public let event: String?
        /// The default value assigned to the property when the component is imported into an app.
        public let importedValue: String?
        /// The data model to use to assign a value to the component property.
        public let model: String?
        /// The name of the component's property that is affected by an event.
        public let property: String?
        /// The component type.
        public let type: String?
        /// An authenticated user attribute to use to assign a value to the component property.
        public let userAttribute: String?
        /// The value to assign to the component property.
        public let value: String?

        public init(bindingProperties: ComponentPropertyBindingProperties? = nil, bindings: [String: FormBindingElement]? = nil, collectionBindingProperties: ComponentPropertyBindingProperties? = nil, componentName: String? = nil, concat: [ComponentProperty]? = nil, condition: ComponentConditionProperty? = nil, configured: Bool? = nil, defaultValue: String? = nil, event: String? = nil, importedValue: String? = nil, model: String? = nil, property: String? = nil, type: String? = nil, userAttribute: String? = nil, value: String? = nil) {
            self.bindingProperties = bindingProperties
            self.bindings = bindings
            self.collectionBindingProperties = collectionBindingProperties
            self.componentName = componentName
            self.concat = concat
            self.condition = condition
            self.configured = configured
            self.defaultValue = defaultValue
            self.event = event
            self.importedValue = importedValue
            self.model = model
            self.property = property
            self.type = type
            self.userAttribute = userAttribute
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case bindingProperties
            case bindings
            case collectionBindingProperties
            case componentName
            case concat
            case condition
            case configured
            case defaultValue
            case event
            case importedValue
            case model
            case property
            case type
            case userAttribute
            case value
        }
    }

    public struct ComponentPropertyBindingProperties: AWSEncodableShape & AWSDecodableShape {
        /// The data field to bind the property to.
        public let field: String?
        /// The component property to bind to the data field.
        public let property: String

        public init(field: String? = nil, property: String) {
            self.field = field
            self.property = property
        }

        private enum CodingKeys: String, CodingKey {
            case field
            case property
        }
    }

    public struct ComponentSummary: AWSDecodableShape {
        /// The unique ID of the Amplify app associated with the component.
        public let appId: String
        /// The component type.
        public let componentType: String
        /// The name of the backend environment that is a part of the Amplify app.
        public let environmentName: String
        /// The unique ID of the component.
        public let id: String
        /// The name of the component.
        public let name: String

        public init(appId: String, componentType: String, environmentName: String, id: String, name: String) {
            self.appId = appId
            self.componentType = componentType
            self.environmentName = environmentName
            self.id = id
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case appId
            case componentType
            case environmentName
            case id
            case name
        }
    }

    public struct ComponentVariant: AWSEncodableShape & AWSDecodableShape {
        /// The properties of the component variant that can be overriden when customizing an instance of the component. You can't specify tags as a valid property for overrides.
        public let overrides: [String: [String: String]]?
        /// The combination of variants that comprise this variant. You can't specify tags as a valid property for variantValues.
        public let variantValues: [String: String]?

        public init(overrides: [String: [String: String]]? = nil, variantValues: [String: String]? = nil) {
            self.overrides = overrides
            self.variantValues = variantValues
        }

        private enum CodingKeys: String, CodingKey {
            case overrides
            case variantValues
        }
    }

    public struct CreateComponentData: AWSEncodableShape {
        /// The data binding information for the component's properties.
        public let bindingProperties: [String: ComponentBindingPropertiesValue]
        /// A list of child components that are instances of the main component.
        public let children: [ComponentChild]?
        /// The data binding configuration for customizing a component's properties. Use this for a collection component.
        public let collectionProperties: [String: ComponentDataConfiguration]?
        /// The component type. This can be an Amplify custom UI component or another custom component.
        public let componentType: String
        /// The event configuration for the component. Use for the workflow feature in Amplify Studio that allows you to bind events and actions to components.
        public let events: [String: ComponentEvent]?
        /// The name of the component
        public let name: String
        /// Describes the component properties that can be overriden to customize an instance of the component.
        public let overrides: [String: [String: String]]
        /// Describes the component's properties.
        public let properties: [String: ComponentProperty]
        /// The schema version of the component when it was imported.
        public let schemaVersion: String?
        /// The unique ID of the component in its original source system, such as Figma.
        public let sourceId: String?
        /// One or more key-value pairs to use when tagging the component data.
        public let tags: [String: String]?
        /// A list of the unique variants of this component.
        public let variants: [ComponentVariant]

        public init(bindingProperties: [String: ComponentBindingPropertiesValue], children: [ComponentChild]? = nil, collectionProperties: [String: ComponentDataConfiguration]? = nil, componentType: String, events: [String: ComponentEvent]? = nil, name: String, overrides: [String: [String: String]], properties: [String: ComponentProperty], schemaVersion: String? = nil, sourceId: String? = nil, tags: [String: String]? = nil, variants: [ComponentVariant]) {
            self.bindingProperties = bindingProperties
            self.children = children
            self.collectionProperties = collectionProperties
            self.componentType = componentType
            self.events = events
            self.name = name
            self.overrides = overrides
            self.properties = properties
            self.schemaVersion = schemaVersion
            self.sourceId = sourceId
            self.tags = tags
            self.variants = variants
        }

        public func validate(name: String) throws {
            try self.validate(self.componentType, name: "componentType", parent: name, max: 255)
            try self.validate(self.componentType, name: "componentType", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, max: 255)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 1)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case bindingProperties
            case children
            case collectionProperties
            case componentType
            case events
            case name
            case overrides
            case properties
            case schemaVersion
            case sourceId
            case tags
            case variants
        }
    }

    public struct CreateComponentRequest: AWSEncodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "componentToCreate"
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "clientToken", location: .querystring("clientToken")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName"))
        ]

        /// The unique ID of the Amplify app to associate with the component.
        public let appId: String
        /// The unique client token.
        public let clientToken: String?
        /// Represents the configuration of the component to create.
        public let componentToCreate: CreateComponentData
        /// The name of the backend environment that is a part of the Amplify app.
        public let environmentName: String

        public init(appId: String, clientToken: String? = CreateComponentRequest.idempotencyToken(), componentToCreate: CreateComponentData, environmentName: String) {
            self.appId = appId
            self.clientToken = clientToken
            self.componentToCreate = componentToCreate
            self.environmentName = environmentName
        }

        public func validate(name: String) throws {
            try self.componentToCreate.validate(name: "\(name).componentToCreate")
        }

        private enum CodingKeys: String, CodingKey {
            case componentToCreate
        }
    }

    public struct CreateComponentResponse: AWSDecodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "entity"

        /// Describes the configuration of the new component.
        public let entity: Component?

        public init(entity: Component? = nil) {
            self.entity = entity
        }

        private enum CodingKeys: String, CodingKey {
            case entity
        }
    }

    public struct CreateFormData: AWSEncodableShape {
        /// The FormCTA object that stores the call to action configuration for the form.
        public let cta: FormCTA?
        /// The type of data source to use to create the form.
        public let dataType: FormDataTypeConfig
        /// The configuration information for the form's fields.
        public let fields: [String: FieldConfig]
        /// Specifies whether to perform a create or update action on the form.
        public let formActionType: FormActionType
        /// The name of the form.
        public let name: String
        /// The schema version of the form.
        public let schemaVersion: String
        /// The configuration information for the visual helper elements for the form. These elements are not associated with any data.
        public let sectionalElements: [String: SectionalElement]
        /// The configuration for the form's style.
        public let style: FormStyle
        /// One or more key-value pairs to use when tagging the form data.
        public let tags: [String: String]?

        public init(cta: FormCTA? = nil, dataType: FormDataTypeConfig, fields: [String: FieldConfig], formActionType: FormActionType, name: String, schemaVersion: String, sectionalElements: [String: SectionalElement], style: FormStyle, tags: [String: String]? = nil) {
            self.cta = cta
            self.dataType = dataType
            self.fields = fields
            self.formActionType = formActionType
            self.name = name
            self.schemaVersion = schemaVersion
            self.sectionalElements = sectionalElements
            self.style = style
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 255)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 1)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case cta
            case dataType
            case fields
            case formActionType
            case name
            case schemaVersion
            case sectionalElements
            case style
            case tags
        }
    }

    public struct CreateFormRequest: AWSEncodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "formToCreate"
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "clientToken", location: .querystring("clientToken")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName"))
        ]

        /// The unique ID of the Amplify app to associate with the form.
        public let appId: String
        /// The unique client token.
        public let clientToken: String?
        /// The name of the backend environment that is a part of the Amplify app.
        public let environmentName: String
        /// Represents the configuration of the form to create.
        public let formToCreate: CreateFormData

        public init(appId: String, clientToken: String? = CreateFormRequest.idempotencyToken(), environmentName: String, formToCreate: CreateFormData) {
            self.appId = appId
            self.clientToken = clientToken
            self.environmentName = environmentName
            self.formToCreate = formToCreate
        }

        public func validate(name: String) throws {
            try self.formToCreate.validate(name: "\(name).formToCreate")
        }

        private enum CodingKeys: String, CodingKey {
            case formToCreate
        }
    }

    public struct CreateFormResponse: AWSDecodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "entity"

        /// Describes the configuration of the new form.
        public let entity: Form?

        public init(entity: Form? = nil) {
            self.entity = entity
        }

        private enum CodingKeys: String, CodingKey {
            case entity
        }
    }

    public struct CreateThemeData: AWSEncodableShape {
        /// The name of the theme.
        public let name: String
        /// Describes the properties that can be overriden to customize an instance of the theme.
        public let overrides: [ThemeValues]?
        /// One or more key-value pairs to use when tagging the theme data.
        public let tags: [String: String]?
        /// A list of key-value pairs that deﬁnes the properties of the theme.
        public let values: [ThemeValues]

        public init(name: String, overrides: [ThemeValues]? = nil, tags: [String: String]? = nil, values: [ThemeValues]) {
            self.name = name
            self.overrides = overrides
            self.tags = tags
            self.values = values
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 255)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 1)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case name
            case overrides
            case tags
            case values
        }
    }

    public struct CreateThemeRequest: AWSEncodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "themeToCreate"
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "clientToken", location: .querystring("clientToken")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName"))
        ]

        /// The unique ID of the Amplify app associated with the theme.
        public let appId: String
        /// The unique client token.
        public let clientToken: String?
        /// The name of the backend environment that is a part of the Amplify app.
        public let environmentName: String
        /// Represents the configuration of the theme to create.
        public let themeToCreate: CreateThemeData

        public init(appId: String, clientToken: String? = CreateThemeRequest.idempotencyToken(), environmentName: String, themeToCreate: CreateThemeData) {
            self.appId = appId
            self.clientToken = clientToken
            self.environmentName = environmentName
            self.themeToCreate = themeToCreate
        }

        public func validate(name: String) throws {
            try self.themeToCreate.validate(name: "\(name).themeToCreate")
        }

        private enum CodingKeys: String, CodingKey {
            case themeToCreate
        }
    }

    public struct CreateThemeResponse: AWSDecodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "entity"

        /// Describes the configuration of the new theme.
        public let entity: Theme?

        public init(entity: Theme? = nil) {
            self.entity = entity
        }

        private enum CodingKeys: String, CodingKey {
            case entity
        }
    }

    public struct DeleteComponentRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "id", location: .uri("id"))
        ]

        /// The unique ID of the Amplify app associated with the component to delete.
        public let appId: String
        /// The name of the backend environment that is a part of the Amplify app.
        public let environmentName: String
        /// The unique ID of the component to delete.
        public let id: String

        public init(appId: String, environmentName: String, id: String) {
            self.appId = appId
            self.environmentName = environmentName
            self.id = id
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteFormRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "id", location: .uri("id"))
        ]

        /// The unique ID of the Amplify app associated with the form to delete.
        public let appId: String
        /// The name of the backend environment that is a part of the Amplify app.
        public let environmentName: String
        /// The unique ID of the form to delete.
        public let id: String

        public init(appId: String, environmentName: String, id: String) {
            self.appId = appId
            self.environmentName = environmentName
            self.id = id
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteThemeRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "id", location: .uri("id"))
        ]

        /// The unique ID of the Amplify app associated with the theme to delete.
        public let appId: String
        /// The name of the backend environment that is a part of the Amplify app.
        public let environmentName: String
        /// The unique ID of the theme to delete.
        public let id: String

        public init(appId: String, environmentName: String, id: String) {
            self.appId = appId
            self.environmentName = environmentName
            self.id = id
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ExchangeCodeForTokenRequest: AWSEncodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "request"
        public static var _encoding = [
            AWSMemberEncoding(label: "provider", location: .uri("provider"))
        ]

        /// The third-party provider for the token. The only valid value is figma.
        public let provider: TokenProviders
        /// Describes the configuration of the request.
        public let request: ExchangeCodeForTokenRequestBody

        public init(provider: TokenProviders, request: ExchangeCodeForTokenRequestBody) {
            self.provider = provider
            self.request = request
        }

        private enum CodingKeys: String, CodingKey {
            case request
        }
    }

    public struct ExchangeCodeForTokenRequestBody: AWSEncodableShape {
        /// The access code to send in the request.
        public let code: String
        /// The location of the application that will receive the access code.
        public let redirectUri: String

        public init(code: String, redirectUri: String) {
            self.code = code
            self.redirectUri = redirectUri
        }

        private enum CodingKeys: String, CodingKey {
            case code
            case redirectUri
        }
    }

    public struct ExchangeCodeForTokenResponse: AWSDecodableShape {
        /// The access token.
        public let accessToken: String
        /// The date and time when the new access token expires.
        public let expiresIn: Int
        /// The token to use to refresh a previously issued access token that might have expired.
        public let refreshToken: String

        public init(accessToken: String, expiresIn: Int, refreshToken: String) {
            self.accessToken = accessToken
            self.expiresIn = expiresIn
            self.refreshToken = refreshToken
        }

        private enum CodingKeys: String, CodingKey {
            case accessToken
            case expiresIn
            case refreshToken
        }
    }

    public struct ExportComponentsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken"))
        ]

        /// The unique ID of the Amplify app to export components to.
        public let appId: String
        /// The name of the backend environment that is a part of the Amplify app.
        public let environmentName: String
        /// The token to request the next page of results.
        public let nextToken: String?

        public init(appId: String, environmentName: String, nextToken: String? = nil) {
            self.appId = appId
            self.environmentName = environmentName
            self.nextToken = nextToken
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ExportComponentsResponse: AWSDecodableShape {
        /// Represents the configuration of the exported components.
        public let entities: [Component]
        /// The pagination token that's included if more results are available.
        public let nextToken: String?

        public init(entities: [Component], nextToken: String? = nil) {
            self.entities = entities
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case entities
            case nextToken
        }
    }

    public struct ExportFormsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken"))
        ]

        /// The unique ID of the Amplify app to export forms to.
        public let appId: String
        /// The name of the backend environment that is a part of the Amplify app.
        public let environmentName: String
        /// The token to request the next page of results.
        public let nextToken: String?

        public init(appId: String, environmentName: String, nextToken: String? = nil) {
            self.appId = appId
            self.environmentName = environmentName
            self.nextToken = nextToken
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ExportFormsResponse: AWSDecodableShape {
        /// Represents the configuration of the exported forms.
        public let entities: [Form]
        /// The pagination token that's included if more results are available.
        public let nextToken: String?

        public init(entities: [Form], nextToken: String? = nil) {
            self.entities = entities
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case entities
            case nextToken
        }
    }

    public struct ExportThemesRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken"))
        ]

        /// The unique ID of the Amplify app to export the themes to.
        public let appId: String
        /// The name of the backend environment that is part of the Amplify app.
        public let environmentName: String
        /// The token to request the next page of results.
        public let nextToken: String?

        public init(appId: String, environmentName: String, nextToken: String? = nil) {
            self.appId = appId
            self.environmentName = environmentName
            self.nextToken = nextToken
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ExportThemesResponse: AWSDecodableShape {
        /// Represents the configuration of the exported themes.
        public let entities: [Theme]
        /// The pagination token that's included if more results are available.
        public let nextToken: String?

        public init(entities: [Theme], nextToken: String? = nil) {
            self.entities = entities
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case entities
            case nextToken
        }
    }

    public struct FieldConfig: AWSEncodableShape & AWSDecodableShape {
        /// Specifies whether to hide a field.
        public let excluded: Bool?
        /// Describes the configuration for the default input value to display for a field.
        public let inputType: FieldInputConfig?
        /// The label for the field.
        public let label: String?
        /// Specifies the field position.
        public let position: FieldPosition?
        /// The validations to perform on the value in the field.
        public let validations: [FieldValidationConfiguration]?

        public init(excluded: Bool? = nil, inputType: FieldInputConfig? = nil, label: String? = nil, position: FieldPosition? = nil, validations: [FieldValidationConfiguration]? = nil) {
            self.excluded = excluded
            self.inputType = inputType
            self.label = label
            self.position = position
            self.validations = validations
        }

        private enum CodingKeys: String, CodingKey {
            case excluded
            case inputType
            case label
            case position
            case validations
        }
    }

    public struct FieldInputConfig: AWSEncodableShape & AWSDecodableShape {
        /// Specifies whether a field has a default value.
        public let defaultChecked: Bool?
        /// The default country code for a phone number.
        public let defaultCountryCode: String?
        /// The default value for the field.
        public let defaultValue: String?
        /// The text to display to describe the field.
        public let descriptiveText: String?
        /// Specifies whether to render the field as an array. This property is ignored if the dataSourceType for the form is a Data Store.
        public let isArray: Bool?
        /// The maximum value to display for the field.
        public let maxValue: Float?
        /// The minimum value to display for the field.
        public let minValue: Float?
        /// The name of the field.
        public let name: String?
        /// The text to display as a placeholder for the field.
        public let placeholder: String?
        /// Specifies a read only field.
        public let readOnly: Bool?
        /// Specifies a field that requires input.
        public let required: Bool?
        /// The stepping increment for a numeric value in a field.
        public let step: Float?
        /// The input type for the field.
        public let type: String
        /// The value for the field.
        public let value: String?
        /// The information to use to customize the input fields with data at runtime.
        public let valueMappings: ValueMappings?

        public init(defaultChecked: Bool? = nil, defaultCountryCode: String? = nil, defaultValue: String? = nil, descriptiveText: String? = nil, isArray: Bool? = nil, maxValue: Float? = nil, minValue: Float? = nil, name: String? = nil, placeholder: String? = nil, readOnly: Bool? = nil, required: Bool? = nil, step: Float? = nil, type: String, value: String? = nil, valueMappings: ValueMappings? = nil) {
            self.defaultChecked = defaultChecked
            self.defaultCountryCode = defaultCountryCode
            self.defaultValue = defaultValue
            self.descriptiveText = descriptiveText
            self.isArray = isArray
            self.maxValue = maxValue
            self.minValue = minValue
            self.name = name
            self.placeholder = placeholder
            self.readOnly = readOnly
            self.required = required
            self.step = step
            self.type = type
            self.value = value
            self.valueMappings = valueMappings
        }

        private enum CodingKeys: String, CodingKey {
            case defaultChecked
            case defaultCountryCode
            case defaultValue
            case descriptiveText
            case isArray
            case maxValue
            case minValue
            case name
            case placeholder
            case readOnly
            case required
            case step
            case type
            case value
            case valueMappings
        }
    }

    public struct FieldValidationConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// The validation to perform on a number value.
        public let numValues: [Int]?
        /// The validation to perform on a string value.
        public let strValues: [String]?
        /// The validation to perform on an object type.
        public let type: String
        /// The validation message to display.
        public let validationMessage: String?

        public init(numValues: [Int]? = nil, strValues: [String]? = nil, type: String, validationMessage: String? = nil) {
            self.numValues = numValues
            self.strValues = strValues
            self.type = type
            self.validationMessage = validationMessage
        }

        private enum CodingKeys: String, CodingKey {
            case numValues
            case strValues
            case type
            case validationMessage
        }
    }

    public struct Form: AWSDecodableShape {
        /// The unique ID of the Amplify app associated with the form.
        public let appId: String
        /// Stores the call to action configuration for the form.
        public let cta: FormCTA?
        /// The type of data source to use to create the form.
        public let dataType: FormDataTypeConfig
        /// The name of the backend environment that is a part of the Amplify app.
        public let environmentName: String
        /// Stores the information about the form's fields.
        public let fields: [String: FieldConfig]
        /// The operation to perform on the specified form.
        public let formActionType: FormActionType
        /// The unique ID of the form.
        public let id: String
        /// The name of the form.
        public let name: String
        /// The schema version of the form when it was imported.
        public let schemaVersion: String
        /// Stores the visual helper elements for the form that are not associated with any data.
        public let sectionalElements: [String: SectionalElement]
        /// Stores the configuration for the form's style.
        public let style: FormStyle
        /// One or more key-value pairs to use when tagging the form.
        public let tags: [String: String]?

        public init(appId: String, cta: FormCTA? = nil, dataType: FormDataTypeConfig, environmentName: String, fields: [String: FieldConfig], formActionType: FormActionType, id: String, name: String, schemaVersion: String, sectionalElements: [String: SectionalElement], style: FormStyle, tags: [String: String]? = nil) {
            self.appId = appId
            self.cta = cta
            self.dataType = dataType
            self.environmentName = environmentName
            self.fields = fields
            self.formActionType = formActionType
            self.id = id
            self.name = name
            self.schemaVersion = schemaVersion
            self.sectionalElements = sectionalElements
            self.style = style
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case appId
            case cta
            case dataType
            case environmentName
            case fields
            case formActionType
            case id
            case name
            case schemaVersion
            case sectionalElements
            case style
            case tags
        }
    }

    public struct FormBindingElement: AWSEncodableShape & AWSDecodableShape {
        /// The name of the component to retrieve a value from.
        public let element: String
        /// The property to retrieve a value from.
        public let property: String

        public init(element: String, property: String) {
            self.element = element
            self.property = property
        }

        private enum CodingKeys: String, CodingKey {
            case element
            case property
        }
    }

    public struct FormButton: AWSEncodableShape & AWSDecodableShape {
        /// Describes the button's properties.
        public let children: String?
        /// Specifies whether the button is visible on the form.
        public let excluded: Bool?
        /// The position of the button.
        public let position: FieldPosition?

        public init(children: String? = nil, excluded: Bool? = nil, position: FieldPosition? = nil) {
            self.children = children
            self.excluded = excluded
            self.position = position
        }

        private enum CodingKeys: String, CodingKey {
            case children
            case excluded
            case position
        }
    }

    public struct FormCTA: AWSEncodableShape & AWSDecodableShape {
        /// Displays a cancel button.
        public let cancel: FormButton?
        /// Displays a clear button.
        public let clear: FormButton?
        /// The position of the button.
        public let position: FormButtonsPosition?
        /// Displays a submit button.
        public let submit: FormButton?

        public init(cancel: FormButton? = nil, clear: FormButton? = nil, position: FormButtonsPosition? = nil, submit: FormButton? = nil) {
            self.cancel = cancel
            self.clear = clear
            self.position = position
            self.submit = submit
        }

        private enum CodingKeys: String, CodingKey {
            case cancel
            case clear
            case position
            case submit
        }
    }

    public struct FormDataTypeConfig: AWSEncodableShape & AWSDecodableShape {
        /// The data source type, either an Amplify DataStore model or a custom data type.
        public let dataSourceType: FormDataSourceType
        /// The unique name of the data type you are using as the data source for the form.
        public let dataTypeName: String

        public init(dataSourceType: FormDataSourceType, dataTypeName: String) {
            self.dataSourceType = dataSourceType
            self.dataTypeName = dataTypeName
        }

        private enum CodingKeys: String, CodingKey {
            case dataSourceType
            case dataTypeName
        }
    }

    public struct FormInputValueProperty: AWSEncodableShape & AWSDecodableShape {
        /// The value to assign to the input field.
        public let value: String?

        public init(value: String? = nil) {
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case value
        }
    }

    public struct FormStyle: AWSEncodableShape & AWSDecodableShape {
        /// The spacing for the horizontal gap.
        public let horizontalGap: FormStyleConfig?
        /// The size of the outer padding for the form.
        public let outerPadding: FormStyleConfig?
        /// The spacing for the vertical gap.
        public let verticalGap: FormStyleConfig?

        public init(horizontalGap: FormStyleConfig? = nil, outerPadding: FormStyleConfig? = nil, verticalGap: FormStyleConfig? = nil) {
            self.horizontalGap = horizontalGap
            self.outerPadding = outerPadding
            self.verticalGap = verticalGap
        }

        private enum CodingKeys: String, CodingKey {
            case horizontalGap
            case outerPadding
            case verticalGap
        }
    }

    public struct FormSummary: AWSDecodableShape {
        /// The unique ID for the app associated with the form summary.
        public let appId: String
        /// The form's data source type.
        public let dataType: FormDataTypeConfig
        /// The name of the backend environment that is part of the Amplify app.
        public let environmentName: String
        /// The type of operation to perform on the form.
        public let formActionType: FormActionType
        /// The ID of the form.
        public let id: String
        /// The name of the form.
        public let name: String

        public init(appId: String, dataType: FormDataTypeConfig, environmentName: String, formActionType: FormActionType, id: String, name: String) {
            self.appId = appId
            self.dataType = dataType
            self.environmentName = environmentName
            self.formActionType = formActionType
            self.id = id
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case appId
            case dataType
            case environmentName
            case formActionType
            case id
            case name
        }
    }

    public struct GetComponentRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "id", location: .uri("id"))
        ]

        /// The unique ID of the Amplify app.
        public let appId: String
        /// The name of the backend environment that is part of the Amplify app.
        public let environmentName: String
        /// The unique ID of the component.
        public let id: String

        public init(appId: String, environmentName: String, id: String) {
            self.appId = appId
            self.environmentName = environmentName
            self.id = id
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetComponentResponse: AWSDecodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "component"

        /// Represents the configuration settings for the component.
        public let component: Component?

        public init(component: Component? = nil) {
            self.component = component
        }

        private enum CodingKeys: String, CodingKey {
            case component
        }
    }

    public struct GetFormRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "id", location: .uri("id"))
        ]

        /// The unique ID of the Amplify app.
        public let appId: String
        /// The name of the backend environment that is part of the Amplify app.
        public let environmentName: String
        /// The unique ID of the form.
        public let id: String

        public init(appId: String, environmentName: String, id: String) {
            self.appId = appId
            self.environmentName = environmentName
            self.id = id
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetFormResponse: AWSDecodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "form"

        /// Represents the configuration settings for the form.
        public let form: Form?

        public init(form: Form? = nil) {
            self.form = form
        }

        private enum CodingKeys: String, CodingKey {
            case form
        }
    }

    public struct GetMetadataRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName"))
        ]

        /// The unique ID of the Amplify app.
        public let appId: String
        /// The name of the backend environment that is part of the Amplify app.
        public let environmentName: String

        public init(appId: String, environmentName: String) {
            self.appId = appId
            self.environmentName = environmentName
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetMetadataResponse: AWSDecodableShape {
        /// Represents the configuration settings for the features metadata.
        public let features: [String: String]

        public init(features: [String: String]) {
            self.features = features
        }

        private enum CodingKeys: String, CodingKey {
            case features
        }
    }

    public struct GetThemeRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "id", location: .uri("id"))
        ]

        /// The unique ID of the Amplify app.
        public let appId: String
        /// The name of the backend environment that is part of the Amplify app.
        public let environmentName: String
        /// The unique ID for the theme.
        public let id: String

        public init(appId: String, environmentName: String, id: String) {
            self.appId = appId
            self.environmentName = environmentName
            self.id = id
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetThemeResponse: AWSDecodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "theme"

        /// Represents the configuration settings for the theme.
        public let theme: Theme?

        public init(theme: Theme? = nil) {
            self.theme = theme
        }

        private enum CodingKeys: String, CodingKey {
            case theme
        }
    }

    public struct ListComponentsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "maxResults", location: .querystring("maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken"))
        ]

        /// The unique ID for the Amplify app.
        public let appId: String
        /// The name of the backend environment that is a part of the Amplify app.
        public let environmentName: String
        /// The maximum number of components to retrieve.
        public let maxResults: Int?
        /// The token to request the next page of results.
        public let nextToken: String?

        public init(appId: String, environmentName: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.appId = appId
            self.environmentName = environmentName
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListComponentsResponse: AWSDecodableShape {
        /// The list of components for the Amplify app.
        public let entities: [ComponentSummary]
        /// The pagination token that's included if more results are available.
        public let nextToken: String?

        public init(entities: [ComponentSummary], nextToken: String? = nil) {
            self.entities = entities
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case entities
            case nextToken
        }
    }

    public struct ListFormsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "maxResults", location: .querystring("maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken"))
        ]

        /// The unique ID for the Amplify app.
        public let appId: String
        /// The name of the backend environment that is a part of the Amplify app.
        public let environmentName: String
        /// The maximum number of forms to retrieve.
        public let maxResults: Int?
        /// The token to request the next page of results.
        public let nextToken: String?

        public init(appId: String, environmentName: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.appId = appId
            self.environmentName = environmentName
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListFormsResponse: AWSDecodableShape {
        /// The list of forms for the Amplify app.
        public let entities: [FormSummary]
        /// The pagination token that's included if more results are available.
        public let nextToken: String?

        public init(entities: [FormSummary], nextToken: String? = nil) {
            self.entities = entities
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case entities
            case nextToken
        }
    }

    public struct ListThemesRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "maxResults", location: .querystring("maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken"))
        ]

        /// The unique ID for the Amplify app.
        public let appId: String
        /// The name of the backend environment that is a part of the Amplify app.
        public let environmentName: String
        /// The maximum number of theme results to return in the response.
        public let maxResults: Int?
        /// The token to request the next page of results.
        public let nextToken: String?

        public init(appId: String, environmentName: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.appId = appId
            self.environmentName = environmentName
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListThemesResponse: AWSDecodableShape {
        /// The list of themes for the Amplify app.
        public let entities: [ThemeSummary]
        /// The pagination token that's returned if more results are available.
        public let nextToken: String?

        public init(entities: [ThemeSummary], nextToken: String? = nil) {
            self.entities = entities
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case entities
            case nextToken
        }
    }

    public struct MutationActionSetStateParameter: AWSEncodableShape & AWSDecodableShape {
        /// The name of the component that is being modified.
        public let componentName: String
        /// The name of the component property to apply the state configuration to.
        public let property: String
        /// The state configuration to assign to the property.
        public let set: ComponentProperty

        public init(componentName: String, property: String, set: ComponentProperty) {
            self.componentName = componentName
            self.property = property
            self.set = set
        }

        private enum CodingKeys: String, CodingKey {
            case componentName
            case property
            case set
        }
    }

    public struct Predicate: AWSEncodableShape & AWSDecodableShape {
        /// A list of predicates to combine logically.
        public let and: [Predicate]?
        /// The field to query.
        public let field: String?
        /// The value to use when performing the evaluation.
        public let operand: String?
        /// The operator to use to perform the evaluation.
        public let `operator`: String?
        /// A list of predicates to combine logically.
        public let or: [Predicate]?

        public init(and: [Predicate]? = nil, field: String? = nil, operand: String? = nil, operator: String? = nil, or: [Predicate]? = nil) {
            self.and = and
            self.field = field
            self.operand = operand
            self.`operator` = `operator`
            self.or = or
        }

        private enum CodingKeys: String, CodingKey {
            case and
            case field
            case operand
            case `operator`
            case or
        }
    }

    public struct PutMetadataFlagBody: AWSEncodableShape {
        /// The new information to store.
        public let newValue: String

        public init(newValue: String) {
            self.newValue = newValue
        }

        private enum CodingKeys: String, CodingKey {
            case newValue
        }
    }

    public struct PutMetadataFlagRequest: AWSEncodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "body"
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "featureName", location: .uri("featureName"))
        ]

        /// The unique ID for the Amplify app.
        public let appId: String
        /// The metadata information to store.
        public let body: PutMetadataFlagBody
        /// The name of the backend environment that is part of the Amplify app.
        public let environmentName: String
        /// The name of the feature associated with the metadata.
        public let featureName: String

        public init(appId: String, body: PutMetadataFlagBody, environmentName: String, featureName: String) {
            self.appId = appId
            self.body = body
            self.environmentName = environmentName
            self.featureName = featureName
        }

        private enum CodingKeys: String, CodingKey {
            case body
        }
    }

    public struct RefreshTokenRequest: AWSEncodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "refreshTokenBody"
        public static var _encoding = [
            AWSMemberEncoding(label: "provider", location: .uri("provider"))
        ]

        /// The third-party provider for the token. The only valid value is figma.
        public let provider: TokenProviders
        /// Information about the refresh token request.
        public let refreshTokenBody: RefreshTokenRequestBody

        public init(provider: TokenProviders, refreshTokenBody: RefreshTokenRequestBody) {
            self.provider = provider
            self.refreshTokenBody = refreshTokenBody
        }

        private enum CodingKeys: String, CodingKey {
            case refreshTokenBody
        }
    }

    public struct RefreshTokenRequestBody: AWSEncodableShape {
        /// The token to use to refresh a previously issued access token that might have expired.
        public let token: String

        public init(token: String) {
            self.token = token
        }

        private enum CodingKeys: String, CodingKey {
            case token
        }
    }

    public struct RefreshTokenResponse: AWSDecodableShape {
        /// The access token.
        public let accessToken: String
        /// The date and time when the new access token expires.
        public let expiresIn: Int

        public init(accessToken: String, expiresIn: Int) {
            self.accessToken = accessToken
            self.expiresIn = expiresIn
        }

        private enum CodingKeys: String, CodingKey {
            case accessToken
            case expiresIn
        }
    }

    public struct SectionalElement: AWSEncodableShape & AWSDecodableShape {
        /// Specifies the size of the font for a Heading sectional element. Valid values are 1 | 2 | 3 | 4 | 5 | 6.
        public let level: Int?
        /// Specifies the orientation for a Divider sectional element. Valid values are horizontal or vertical.
        public let orientation: String?
        /// Specifies the position of the text in a field for a Text sectional element.
        public let position: FieldPosition?
        /// The text for a Text sectional element.
        public let text: String?
        /// The type of sectional element. Valid values are Heading, Text, and Divider.
        public let type: String

        public init(level: Int? = nil, orientation: String? = nil, position: FieldPosition? = nil, text: String? = nil, type: String) {
            self.level = level
            self.orientation = orientation
            self.position = position
            self.text = text
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case level
            case orientation
            case position
            case text
            case type
        }
    }

    public struct SortProperty: AWSEncodableShape & AWSDecodableShape {
        /// The direction of the sort, either ascending or descending.
        public let direction: SortDirection
        /// The field to perform the sort on.
        public let field: String

        public init(direction: SortDirection, field: String) {
            self.direction = direction
            self.field = field
        }

        private enum CodingKeys: String, CodingKey {
            case direction
            case field
        }
    }

    public struct Theme: AWSDecodableShape {
        /// The unique ID for the Amplify app associated with the theme.
        public let appId: String
        /// The time that the theme was created.
        public let createdAt: Date
        /// The name of the backend environment that is a part of the Amplify app.
        public let environmentName: String
        /// The ID for the theme.
        public let id: String
        /// The time that the theme was modified.
        public let modifiedAt: Date?
        /// The name of the theme.
        public let name: String
        /// Describes the properties that can be overriden to customize a theme.
        public let overrides: [ThemeValues]?
        /// One or more key-value pairs to use when tagging the theme.
        public let tags: [String: String]?
        /// A list of key-value pairs that defines the properties of the theme.
        public let values: [ThemeValues]

        public init(appId: String, createdAt: Date, environmentName: String, id: String, modifiedAt: Date? = nil, name: String, overrides: [ThemeValues]? = nil, tags: [String: String]? = nil, values: [ThemeValues]) {
            self.appId = appId
            self.createdAt = createdAt
            self.environmentName = environmentName
            self.id = id
            self.modifiedAt = modifiedAt
            self.name = name
            self.overrides = overrides
            self.tags = tags
            self.values = values
        }

        private enum CodingKeys: String, CodingKey {
            case appId
            case createdAt
            case environmentName
            case id
            case modifiedAt
            case name
            case overrides
            case tags
            case values
        }
    }

    public struct ThemeSummary: AWSDecodableShape {
        /// The unique ID for the app associated with the theme summary.
        public let appId: String
        /// The name of the backend environment that is part of the Amplify app.
        public let environmentName: String
        /// The ID of the theme.
        public let id: String
        /// The name of the theme.
        public let name: String

        public init(appId: String, environmentName: String, id: String, name: String) {
            self.appId = appId
            self.environmentName = environmentName
            self.id = id
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case appId
            case environmentName
            case id
            case name
        }
    }

    public struct ThemeValue: AWSEncodableShape & AWSDecodableShape {
        /// A list of key-value pairs that define the theme's properties.
        public let children: [ThemeValues]?
        /// The value of a theme property.
        public let value: String?

        public init(children: [ThemeValues]? = nil, value: String? = nil) {
            self.children = children
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case children
            case value
        }
    }

    public struct ThemeValues: AWSEncodableShape & AWSDecodableShape {
        /// The name of the property.
        public let key: String?
        /// The value of the property.
        public let value: ThemeValue?

        public init(key: String? = nil, value: ThemeValue? = nil) {
            self.key = key
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case key
            case value
        }
    }

    public struct UpdateComponentData: AWSEncodableShape {
        /// The data binding information for the component's properties.
        public let bindingProperties: [String: ComponentBindingPropertiesValue]?
        /// The components that are instances of the main component.
        public let children: [ComponentChild]?
        /// The configuration for binding a component's properties to a data model. Use this for a collection component.
        public let collectionProperties: [String: ComponentDataConfiguration]?
        /// The type of the component. This can be an Amplify custom UI component or another custom component.
        public let componentType: String?
        /// The event configuration for the component. Use for the workflow feature in Amplify Studio that allows you to bind events and actions to components.
        public let events: [String: ComponentEvent]?
        /// The unique ID of the component to update.
        public let id: String?
        /// The name of the component to update.
        public let name: String?
        /// Describes the properties that can be overriden to customize the component.
        public let overrides: [String: [String: String]]?
        /// Describes the component's properties.
        public let properties: [String: ComponentProperty]?
        /// The schema version of the component when it was imported.
        public let schemaVersion: String?
        /// The unique ID of the component in its original source system, such as Figma.
        public let sourceId: String?
        /// A list of the unique variants of the main component being updated.
        public let variants: [ComponentVariant]?

        public init(bindingProperties: [String: ComponentBindingPropertiesValue]? = nil, children: [ComponentChild]? = nil, collectionProperties: [String: ComponentDataConfiguration]? = nil, componentType: String? = nil, events: [String: ComponentEvent]? = nil, id: String? = nil, name: String? = nil, overrides: [String: [String: String]]? = nil, properties: [String: ComponentProperty]? = nil, schemaVersion: String? = nil, sourceId: String? = nil, variants: [ComponentVariant]? = nil) {
            self.bindingProperties = bindingProperties
            self.children = children
            self.collectionProperties = collectionProperties
            self.componentType = componentType
            self.events = events
            self.id = id
            self.name = name
            self.overrides = overrides
            self.properties = properties
            self.schemaVersion = schemaVersion
            self.sourceId = sourceId
            self.variants = variants
        }

        public func validate(name: String) throws {
            try self.validate(self.componentType, name: "componentType", parent: name, max: 255)
            try self.validate(self.componentType, name: "componentType", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, max: 255)
            try self.validate(self.name, name: "name", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case bindingProperties
            case children
            case collectionProperties
            case componentType
            case events
            case id
            case name
            case overrides
            case properties
            case schemaVersion
            case sourceId
            case variants
        }
    }

    public struct UpdateComponentRequest: AWSEncodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "updatedComponent"
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "clientToken", location: .querystring("clientToken")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "id", location: .uri("id"))
        ]

        /// The unique ID for the Amplify app.
        public let appId: String
        /// The unique client token.
        public let clientToken: String?
        /// The name of the backend environment that is part of the Amplify app.
        public let environmentName: String
        /// The unique ID for the component.
        public let id: String
        /// The configuration of the updated component.
        public let updatedComponent: UpdateComponentData

        public init(appId: String, clientToken: String? = UpdateComponentRequest.idempotencyToken(), environmentName: String, id: String, updatedComponent: UpdateComponentData) {
            self.appId = appId
            self.clientToken = clientToken
            self.environmentName = environmentName
            self.id = id
            self.updatedComponent = updatedComponent
        }

        public func validate(name: String) throws {
            try self.updatedComponent.validate(name: "\(name).updatedComponent")
        }

        private enum CodingKeys: String, CodingKey {
            case updatedComponent
        }
    }

    public struct UpdateComponentResponse: AWSDecodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "entity"

        /// Describes the configuration of the updated component.
        public let entity: Component?

        public init(entity: Component? = nil) {
            self.entity = entity
        }

        private enum CodingKeys: String, CodingKey {
            case entity
        }
    }

    public struct UpdateFormData: AWSEncodableShape {
        /// The FormCTA object that stores the call to action configuration for the form.
        public let cta: FormCTA?
        /// The type of data source to use to create the form.
        public let dataType: FormDataTypeConfig?
        /// The configuration information for the form's fields.
        public let fields: [String: FieldConfig]?
        /// Specifies whether to perform a create or update action on the form.
        public let formActionType: FormActionType?
        /// The name of the form.
        public let name: String?
        /// The schema version of the form.
        public let schemaVersion: String?
        /// The configuration information for the visual helper elements for the form. These elements are not associated with any data.
        public let sectionalElements: [String: SectionalElement]?
        /// The configuration for the form's style.
        public let style: FormStyle?

        public init(cta: FormCTA? = nil, dataType: FormDataTypeConfig? = nil, fields: [String: FieldConfig]? = nil, formActionType: FormActionType? = nil, name: String? = nil, schemaVersion: String? = nil, sectionalElements: [String: SectionalElement]? = nil, style: FormStyle? = nil) {
            self.cta = cta
            self.dataType = dataType
            self.fields = fields
            self.formActionType = formActionType
            self.name = name
            self.schemaVersion = schemaVersion
            self.sectionalElements = sectionalElements
            self.style = style
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 255)
            try self.validate(self.name, name: "name", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case cta
            case dataType
            case fields
            case formActionType
            case name
            case schemaVersion
            case sectionalElements
            case style
        }
    }

    public struct UpdateFormRequest: AWSEncodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "updatedForm"
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "clientToken", location: .querystring("clientToken")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "id", location: .uri("id"))
        ]

        /// The unique ID for the Amplify app.
        public let appId: String
        /// The unique client token.
        public let clientToken: String?
        /// The name of the backend environment that is part of the Amplify app.
        public let environmentName: String
        /// The unique ID for the form.
        public let id: String
        /// The request accepts the following data in JSON format.
        public let updatedForm: UpdateFormData

        public init(appId: String, clientToken: String? = UpdateFormRequest.idempotencyToken(), environmentName: String, id: String, updatedForm: UpdateFormData) {
            self.appId = appId
            self.clientToken = clientToken
            self.environmentName = environmentName
            self.id = id
            self.updatedForm = updatedForm
        }

        public func validate(name: String) throws {
            try self.updatedForm.validate(name: "\(name).updatedForm")
        }

        private enum CodingKeys: String, CodingKey {
            case updatedForm
        }
    }

    public struct UpdateFormResponse: AWSDecodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "entity"

        /// Describes the configuration of the updated form.
        public let entity: Form?

        public init(entity: Form? = nil) {
            self.entity = entity
        }

        private enum CodingKeys: String, CodingKey {
            case entity
        }
    }

    public struct UpdateThemeData: AWSEncodableShape {
        /// The unique ID of the theme to update.
        public let id: String?
        /// The name of the theme to update.
        public let name: String?
        /// Describes the properties that can be overriden to customize the theme.
        public let overrides: [ThemeValues]?
        /// A list of key-value pairs that define the theme's properties.
        public let values: [ThemeValues]

        public init(id: String? = nil, name: String? = nil, overrides: [ThemeValues]? = nil, values: [ThemeValues]) {
            self.id = id
            self.name = name
            self.overrides = overrides
            self.values = values
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 255)
            try self.validate(self.name, name: "name", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case id
            case name
            case overrides
            case values
        }
    }

    public struct UpdateThemeRequest: AWSEncodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "updatedTheme"
        public static var _encoding = [
            AWSMemberEncoding(label: "appId", location: .uri("appId")),
            AWSMemberEncoding(label: "clientToken", location: .querystring("clientToken")),
            AWSMemberEncoding(label: "environmentName", location: .uri("environmentName")),
            AWSMemberEncoding(label: "id", location: .uri("id"))
        ]

        /// The unique ID for the Amplify app.
        public let appId: String
        /// The unique client token.
        public let clientToken: String?
        /// The name of the backend environment that is part of the Amplify app.
        public let environmentName: String
        /// The unique ID for the theme.
        public let id: String
        /// The configuration of the updated theme.
        public let updatedTheme: UpdateThemeData

        public init(appId: String, clientToken: String? = UpdateThemeRequest.idempotencyToken(), environmentName: String, id: String, updatedTheme: UpdateThemeData) {
            self.appId = appId
            self.clientToken = clientToken
            self.environmentName = environmentName
            self.id = id
            self.updatedTheme = updatedTheme
        }

        public func validate(name: String) throws {
            try self.updatedTheme.validate(name: "\(name).updatedTheme")
        }

        private enum CodingKeys: String, CodingKey {
            case updatedTheme
        }
    }

    public struct UpdateThemeResponse: AWSDecodableShape & AWSShapeWithPayload {
        /// The key for the payload
        public static let _payloadPath: String = "entity"

        /// Describes the configuration of the updated theme.
        public let entity: Theme?

        public init(entity: Theme? = nil) {
            self.entity = entity
        }

        private enum CodingKeys: String, CodingKey {
            case entity
        }
    }

    public struct ValueMapping: AWSEncodableShape & AWSDecodableShape {
        /// The value to display for the complex object.
        public let displayValue: FormInputValueProperty?
        /// The complex object.
        public let value: FormInputValueProperty

        public init(displayValue: FormInputValueProperty? = nil, value: FormInputValueProperty) {
            self.displayValue = displayValue
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case displayValue
            case value
        }
    }

    public struct ValueMappings: AWSEncodableShape & AWSDecodableShape {
        /// The value and display value pairs.
        public let values: [ValueMapping]

        public init(values: [ValueMapping]) {
            self.values = values
        }

        private enum CodingKeys: String, CodingKey {
            case values
        }
    }
}

// MARK: - Errors

/// Error enum for AmplifyUIBuilder
public struct AmplifyUIBuilderErrorType: AWSErrorType {
    enum Code: String {
        case internalServerException = "InternalServerException"
        case invalidParameterException = "InvalidParameterException"
        case resourceConflictException = "ResourceConflictException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case unauthorizedException = "UnauthorizedException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize AmplifyUIBuilder
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// An internal error has occurred. Please retry your request.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// An invalid or out-of-range value was supplied for the input parameter.
    public static var invalidParameterException: Self { .init(.invalidParameterException) }
    /// The resource specified in the request conflicts with an existing resource.
    public static var resourceConflictException: Self { .init(.resourceConflictException) }
    /// The requested resource does not exist, or access was denied.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// You exceeded your service quota. Service quotas, also referred to as limits, are the maximum number of service resources or operations for your Amazon Web Services account.
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    /// You don&#39;t have permission to perform this operation.
    public static var unauthorizedException: Self { .init(.unauthorizedException) }
}

extension AmplifyUIBuilderErrorType: Equatable {
    public static func == (lhs: AmplifyUIBuilderErrorType, rhs: AmplifyUIBuilderErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension AmplifyUIBuilderErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
